/*
 * Copyright 2002-2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.aop.aspectj.annotation;

import org.springframework.aop.aspectj.AspectInstanceFactory;
import org.springframework.lang.Nullable;

/**
 * Subinterface of {@link org.springframework.aop.aspectj.AspectInstanceFactory}
 * that returns {@link AspectMetadata} associated with AspectJ-annotated classes.
 *
 * <p>Ideally, AspectInstanceFactory would include this method itself, but because
 * AspectMetadata uses Java-5-only {@link org.aspectj.lang.reflect.AjType},
 * we need to split out this subinterface.
 *
 * @author Rod Johnson
 * @since 2.0
 * @see AspectMetadata
 * @see org.aspectj.lang.reflect.AjType
 */
/*
1. 总结
MetadataAwareAspectInstanceFactory 是 AspectInstanceFactory 的子接口，获取AspectJ 注解类的切面实例的工厂对象
	它提供了获取切面元数据和创建互斥锁的方法，是 Spring AOP 处理基于注解的 AspectJ 切面的核心接口
	该接口的设计是为了分离关注点，因为 AspectMetadata 使用了 Java 5 的 AjType，需要单独定义子接口
2. 内部成员说明
	AspectMetadata getAspectMetadata()：返回与此工厂相关的 AspectJ 切面元数据
	Object getAspectCreationMutex()：返回此工厂的最佳创建互斥锁对象，用于保证切面实例创建的线程安全
3. 类关系结构
 AspectInstanceFactory (interface)	核心接口，用于提供 AspectJ 切面的实例
    ├── MetadataAwareAspectInstanceFactory (interface)	（专门用于处理 @AspectJ注解类）AspectInstanceFactory 的子接口，增加了获取切面元数据的能力
    │   ├── BeanFactoryAspectInstanceFactory (class)	使用 Spring 的 BeanFactory 来获取切面实例
    │   │   └── PrototypeAspectInstanceFactory (class)	处理原型作用域切面的实例工厂实现（每次调用 getAspectInstance() 都会创建新的切面实例）
    │   ├── LazySingletonAspectInstanceFactoryDecorator (class)	懒加载单例切面实例工厂装饰器(延迟初始化切面实例，只有在第一次需要时才创建)
    │   ├── SingletonMetadataAwareAspectInstanceFactory (class)	单例模式的元数据感知切面实例工厂(确保切面实例在整个应用生命周期中只创建一次)
    │   └── SimpleMetadataAwareAspectInstanceFactory (class)	简单的元数据感知切面实例工厂(提供基本的元数据访问功能，不依赖 Spring 的 BeanFactory)
    ├── SingletonAspectInstanceFactory (class)	单例切面实例工厂(确保切面实例在整个应用生命周期中只创建一次)
    │   └── SingletonMetadataAwareAspectInstanceFactory (class)	单例模式的元数据感知切面实例工厂(确保切面实例在整个应用生命周期中只创建一次)
    ├── SimpleBeanFactoryAwareAspectInstanceFactory (class)	简单的 BeanFactory 感知切面实例工厂(简单地包装了 BeanFactory 的功能，不提供额外的元数据支持)
    └── SimpleAspectInstanceFactory (class)	简单的切面实例工厂(确保切面实例在整个应用生命周期中只创建一次)

相关类和接口区别
	AspectInstanceFactory：核心接口，用于提供 AspectJ 切面的实例
	MetadataAwareAspectInstanceFactory：AspectInstanceFactory 的子接口，增加了获取切面元数据的能力
	BeanFactoryAspectInstanceFactory：基于 Spring BeanFactory 的切面实例工厂实现
	PrototypeAspectInstanceFactory：处理原型作用域切面的实例工厂实现
	LazySingletonAspectInstanceFactoryDecorator：懒加载单例切面实例工厂装饰器
	SingletonMetadataAwareAspectInstanceFactory：单例模式的元数据感知切面实例工厂
	SimpleMetadataAwareAspectInstanceFactory：简单的元数据感知切面实例工厂
	SingletonAspectInstanceFactory：单例切面实例工厂
	SimpleBeanFactoryAwareAspectInstanceFactory：简单的 BeanFactory 感知切面实例工厂
	SimpleAspectInstanceFactory：简单的切面实例工厂
4. 使用场景
	Spring AOP 在处理基于注解的 AspectJ 切面时，需要获取切面的元数据信息
	在创建切面实例时，需要线程安全的互斥锁来保证实例创建的正确性
	作为各种具体切面实例工厂实现的统一接口，提供元数据访问能力
5. 实际代码应用示例
// 在 ReflectiveAspectJAdvisorFactory 中使用
public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory {

    @Override
    public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
        // 获取切面元数据
        AspectMetadata aspectMetadata = aspectInstanceFactory.getAspectMetadata();
        Class<?> aspectClass = aspectMetadata.getAspectClass();
        String aspectName = aspectMetadata.getAspectName();

        // 使用元数据进行后续处理...
        return new ArrayList<>();
    }
}

// 具体实现类示例
public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInstanceFactory {
    private final AspectMetadata aspectMetadata;

    @Override
    public AspectMetadata getAspectMetadata() {
        return this.aspectMetadata;
    }

    @Override
    public Object getAspectCreationMutex() {
        return this; // 使用自身作为互斥锁
    }
}

 */
public interface MetadataAwareAspectInstanceFactory extends AspectInstanceFactory {

	/**
	 * Return the AspectJ AspectMetadata for this factory's aspect.
	 * @return the aspect metadata
	 */
	AspectMetadata getAspectMetadata();

	/**
	 * Return the best possible creation mutex for this factory.
	 * @return the mutex object (may be {@code null} for no mutex to use)
	 * @since 4.3
	 */
	@Nullable
	Object getAspectCreationMutex();

}
